/*
 * Copyright © 2018 www.noark.xyz All Rights Reserved.
 *
 * 感谢您选择Noark框架，希望我们的努力能为您提供一个简单、易用、稳定的服务器端框架 ！
 * 除非符合Noark许可协议，否则不得使用该文件，您可以下载许可协议文件：
 *
 *        http://www.noark.xyz/LICENSE
 *
 * 1.未经许可，任何公司及个人不得以任何方式或理由对本框架进行修改、使用和传播;
 * 2.禁止在本项目或任何子项目的基础上发展任何派生版本、修改版本或第三方版本;
 * 3.无论你对源代码做出任何修改和改进，版权都归Noark研发团队所有，我们保留所有权利;
 * 4.凡侵犯Noark版权等知识产权的，必依法追究其法律责任，特此郑重法律声明！
 */
package xyz.noark.game.config;

import xyz.noark.core.lang.PairHashMap;
import xyz.noark.core.util.HttpUtils;
import xyz.noark.core.util.MapUtils;
import xyz.noark.core.util.RandomUtils;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Nacos服务器信息
 *
 * @author 小流氓[176543888@qq.com]
 * @since 3.4.8
 */
public class NacosServerInfo {
    private final List<String> serverAddrList;
    private final String tenant;

    public NacosServerInfo(List<String> serverAddrList, String tenant) {
        this.serverAddrList = serverAddrList;
        this.tenant = tenant;
    }

    private String randomServerAddr() {
        return RandomUtils.randomList(serverAddrList);
    }

    public String getTenant() {
        return tenant;
    }

    public String httpGet(String dataId, String group) throws IOException {
        StringBuilder url = new StringBuilder(128);
        url.append("http://").append(this.randomServerAddr()).append("/nacos/v1/cs/configs");
        url.append("?dataId=").append(dataId);
        url.append("&group=").append(group);
        url.append("&tenant=").append(this.getTenant());
        Map<String, String> requestProperty = this.doAuthExtra(url);
        return HttpUtils.get(url.toString(), requestProperty);
    }

    /**
     * 字段分隔符
     */
    private static final String FIELD_SEPARATOR = "%02";
    /**
     * 配置分隔符
     */
    private static final String CONFIG_SEPARATOR = "%01";

    public String configsListener(PairHashMap<String, String, String> cacheConfigMd5Map, int timeout) {
        StringBuilder url = new StringBuilder(128);
        url.append("http://").append(this.randomServerAddr()).append("/nacos/v1/cs/configs/listener?");
        Map<String, String> requestProperty = this.doAuthExtra(url);

        // Listening-Configs=dataId^2Group^2contentMD5^2tenant^1
        // Listening-Configs=dataId%02group%02contentMD5%02tenant%01
        StringBuilder sb = new StringBuilder(128);
        sb.append("Listening-Configs=");
        cacheConfigMd5Map.forEach((k, v) -> {
            sb.append(k.getLeft()).append(FIELD_SEPARATOR);
            sb.append(k.getRight()).append(FIELD_SEPARATOR);
            sb.append(v).append(FIELD_SEPARATOR);
            sb.append(this.getTenant()).append(CONFIG_SEPARATOR);
        });
        
        Map<String, String> listenerHeader;
        if (requestProperty.isEmpty()) {
            listenerHeader = MapUtils.newHashMap(1);
        } else {
            listenerHeader = new HashMap<>(requestProperty);
        }
        listenerHeader.put("Long-Pulling-Timeout", String.valueOf(NacosConfigManager.TIMEOUT));
        return HttpUtils.post(url.toString(), sb.toString(), timeout, listenerHeader);
    }

    protected Map<String, String> doAuthExtra(StringBuilder sb) {
        // 留给子类去扩展
        return Collections.emptyMap();
    }
}
